package cn.ecasoft.service;

import cn.ecasoft.constant.AllowProperties;
import cn.ecasoft.pojo.ClientSocket;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static cn.ecasoft.service.SocketHandler.register;

/**
 * @Author: LiangChun
 * @Description: Socketserver
 * @DateTime: 2023/2/23
 **/

@Slf4j
@Data
@Component
@NoArgsConstructor
@RefreshScope
public class SocketServer {
    private boolean started;
    private ServerSocket serverSocket;
    // 防止重复创建socket线程链接对象浪费资源
    private ExecutorService executorService = Executors.newCachedThreadPool();
    @Autowired
    private AllowProperties allowProperties;

    public void start(){
        start(null);
    }

    public void start(Integer port)  {
        log.info("port: {}, {}", allowProperties.getPort(), port);
        try {
            serverSocket =  new ServerSocket(port == null ? allowProperties.getPort() : port);
            started = true;
            log.info("Socket服务已启动，占用端口： {}", serverSocket.getLocalPort());
        } catch (IOException e) {
            log.error("端口冲突,异常信息：{}", e);
            System.exit(0);
        }

        while  (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                log.error(e.getMessage());
            }
            try {
                // 开启socket监听
                Socket socket = serverSocket.accept();
                if(!socket.getKeepAlive()) socket.setKeepAlive(true);//true，若长时间没有连接则断开
                if(!socket.getOOBInline())socket.setOOBInline(true);//true,允许发送紧急数据，不做处理
                if(allowProperties.getIfip() && !allowProperties.getIps().contains(socket.getInetAddress().getHostAddress())) continue;
                ClientSocket register = register(socket);
                log.info("请求地址：{},ip:{},分配SocketKey:{}",socket.getInetAddress().getHostName(),socket.getInetAddress().getHostAddress(),register.getKey());
                if (register != null){
                    executorService.submit(register.setTimeout(allowProperties.getTimeout()));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
